<!-- 图层树 -->

<template>
  <ZZDialog class="tree-layer" title="图层管理">
    <el-tree class="tree-content" :data="data" node-key="id">
      <template #default="{ node, data }">
        <el-checkbox
          v-model="data.visible"
          style="margin-right: 8px"
          @change="value => handleCheckChange(value, data)"
        />
        <span class="custom-tree-node">
          <span>{{ node.label }}</span>
          <img
            src="../assets/location.svg"
            title="定位"
            class="img-btn"
            @click="centerAt(data)"
            v-if="data.type != 'group' && data.visible"
          />
          <img
            src="../assets/modify.svg"
            title="编辑"
            class="img-btn"
            @click="modify(data)"
            v-if="data.type == '3dtiles' && data.visible"
          />
        </span>
      </template>
    </el-tree>
  </ZZDialog>
</template>

<script setup>
import { onMounted, onBeforeUnmount, reactive, nextTick, defineAsyncComponent } from 'vue';
import { useViewer } from '../stores/viewer';
import EventBus from '@/common/EventBus';
import { openComponent } from '@/common/DzModalService';
import ZZDialog from '@/common/ZZDialog.vue';

const store = useViewer();

const data = reactive([]);
let viewer;

onMounted(() => {
  refresh();
  // 开启事件监听
  EventBus.on('sceneLoaded', refresh);
});

onBeforeUnmount(() => {
  // 结束事件监听
  EventBus.off('sceneLoaded');
});

const centerAt = function (data) {
  if (!viewer || !viewer.zz) {
    return;
  }
  viewer.zz.centerAtLayer(data.id);
};

const modify = function (data) {
  if (!viewer) {
    return;
  }
  const dialog = defineAsyncComponent(() => import(`../components/Add3DTiles.vue`));
  openComponent(dialog, 'Add3DTiles', { layerId: data.id });
};

const transTree = function (treeArray) {
  const map = new Map();
  for (let i = 0; i < treeArray.length; ++i) {
    const item = treeArray[i];
    map.set(item.id, item);
  }
  const ret = [];
  for (let i = 0; i < treeArray.length; ++i) {
    const item = treeArray[i];
    const pid = item.parentId;
    if (pid && map.has(pid)) {
      const pItem = map.get(pid);
      pItem.children = pItem.children || [];
      pItem.children.push(item);
    } else {
      ret.push(item);
    }
  }
  return ret;
};

const fillData = function (dateTemp, dataRet) {
  for (let i = 0; i < dateTemp.length; ++i) {
    const item = dateTemp[i];

    if (item.children) {
      dataRet.push({ label: item.label, id: item.id, visible: item.visible, type: item.type });
      dataRet[dataRet.length - 1].children = [];
      fillData(item.children, dataRet[dataRet.length - 1].children);
    } else {
      dataRet.push({ label: item.label, id: item.id, visible: item.visible, type: item.type });
    }
  }
};

const refresh = async function () {
  viewer = store.viewer;
  const checked = [];
  if (viewer) {
    data.length = 0;
    let dataTemp = [];
    const layers = viewer.zz.config.operationallayers;
    const objLayer = Object.assign({}, layers);
    for (const ind in objLayer) {
      const item = objLayer[ind];
      dataTemp.push({ label: item.name, id: item.id, parentId: item.parentId, type: item.type, visible: item.visible });
      if (item.visible && item.type != 'group') {
        checked.push(item.id);
      }
    }

    dataTemp = transTree(dataTemp);
    fillData(dataTemp, data);
    await nextTick();
  }
};

const handleCheckChange = (checked, node) => {
  if (node.type != 'group') {
    viewer.zz.setLayerVisible(node.id, checked);
  }
};
</script>

<style scoped>
.tree-layer {
  position: absolute;
  top: 45px;
  left: 5px;
  background-color: rgba(0, 0, 0, 0.5);
  border: 1px solid rgba(32, 160, 255, 0.6);
}

.tree-ctrl {
  position: absolute;
  top: 0px;
  right: 0px;
  cursor: default;
  width: 30px;
  height: 36px;
  text-align: center;
}

.tree-ctrl:hover {
  color: red;
  cursor: default;
}

.tree-content {
  min-width: 150px;
  max-height: 800px;
  overflow: auto;
}

.tree-show {
  width: 26px;
  height: 28px;
  text-align: center;
  line-height: 24px;
}

.layer-tree-title {
  background-color: rgba(0, 0, 0, 0.5);
  height: 36px;
  line-height: 36px;
  padding-left: 8px;
  font-size: 14px;
  border-bottom: 1px solid;
  border-image: linear-gradient(90deg, #2e678f 0, #0cf 49%, rgba(22, 54, 103, 0) 100%) 1 1;
}

.img-btn {
  width: 12px;
  height: 12px;
  margin-left: 4px;
}

:deep(.el-tree-node__content) {
  height: unset;
}

.tree-show:hover {
  color: red;
  cursor: default;
}

.custom-tree-node {
  margin-right: 6px;
}
</style>
